package org.quipu.client;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import java.util.HashMap;
import java.util.Map;
import org.quipu.client.events.AppEvent;
import org.quipu.client.events.AppEventBus;
import org.quipu.client.events.AppEventListener;
import org.quipu.client.events.CurrenciesOutOfDateEvent;
import org.quipu.client.events.CurrencyChangedEvent;
import org.quipu.dto.BookDto;
import org.quipu.dto.CurrencyDto;

public class CurrencyEditPanel extends AppEventWidget implements AppEventListener {

    private final VerticalPanel vPanel;
    private final FlexTable table;
    private final TextBox editBox;
    private final Button submitBtn;
    private final Button removeBtn;
    private final Map<Integer, CurrencyDto> currencyRowCache;
    private Long selectedCurrencyId;

    public CurrencyEditPanel(AppEventBus eventBus, AppCache cache) {
        super(eventBus, cache);
        currencyRowCache = new HashMap<Integer, CurrencyDto>();

        vPanel = new VerticalPanel();
        vPanel.addStyleName("controlPanel");
        editBox = new TextBox();
        editBox.addStyleName("titleShortInput");
        submitBtn = new Button("Создать");
        submitBtn.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                submitCurrency();
            }
        });
        removeBtn = new Button("Удалить");
        removeBtn.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                removeCurrency();
            }
        });
        table = new FlexTable();
        table.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                Cell cell = table.getCellForEvent(event);
                int row = cell.getRowIndex();
                selectCurrency(row);
            }
        });
        vPanel.add(table);
    }

    @Override
    public void init() {
        getEventBus().addListener(CurrenciesOutOfDateEvent.class, this);
    }

    @Override
    public Widget getWidget() {
        return vPanel;
    }

    @Override
    public void handleEvent(AppEvent event) {
        if(event != null) {
            if(event instanceof CurrenciesOutOfDateEvent) {
                refresh();
            }
        }
    }

    private void refresh() {
        table.removeAllRows();
        int row = 0;
        FlexTable.FlexCellFormatter cellFormatter = table.getFlexCellFormatter();
        FlexTable.RowFormatter rowFormatter = table.getRowFormatter();
        currencyRowCache.clear();
        boolean selected = false;
        for(CurrencyDto currency: getCache().getCurrencies()) {
            table.setWidget(row, 0, new Label(currency.getTitle()));
            cellFormatter.setColSpan(row, 0, 2);
            if(selectedCurrencyId != null && currency.getId().equals(selectedCurrencyId)) {
                rowFormatter.addStyleName(row, "tableSelectedRow");
                selected = true;
            }
            rowFormatter.addStyleName(row, "tableSelectableRow");
            currencyRowCache.put(row, currency);
            row++;
        }
//        Window.alert(row + " currencies displayed");
        table.setWidget(row, 0, editBox);
        table.setWidget(row++, 1, submitBtn);
        if(!selected) {
            selectedCurrencyId = null;
        } else {
            table.setWidget(row, 1, removeBtn);
        }
    }

    private void selectCurrency(int row) {
        CurrencyDto currency = currencyRowCache.get(row);
        if(currency != null) {
            if(currency.getId().equals(selectedCurrencyId)) {
                selectedCurrencyId = null;
            } else {
                selectedCurrencyId = currency.getId();
            }
            CurrencyDto selectedCurrency = getCache().getCurrency(selectedCurrencyId);
            editBox.setValue(selectedCurrency == null? "": selectedCurrency.getTitle());
            submitBtn.setText(selectedCurrencyId == null? "Создать": "Сохранить");
            refresh();
        }
    }

    private void removeCurrency() {
        getMainService().removeCurrency(selectedCurrencyId, new AsyncCallback<Void>() {

            public void onSuccess(Void result) {
                getEventBus().fireEvent(new CurrencyChangedEvent(CurrencyEditPanel.this, null));
            }

            public void onFailure(Throwable caught) {
                Window.alert(caught.getMessage());
            }
        });
    }

    private void submitCurrency() {
        BookDto book = getCache().getCurrentBook();
        if(book != null) {
            final CurrencyDto currency = new CurrencyDto();
            if(selectedCurrencyId != null) {
                currency.setId(selectedCurrencyId);
                CurrencyDto selectedCurrency = getCache().getCurrency(selectedCurrencyId);
                if(selectedCurrency != null) {
                    currency.setDicCurrencyId(selectedCurrency.getDicCurrencyId());
                }
            }
            currency.setBookId(book.getId());
            currency.setTitle(editBox.getValue());
            getMainService().submitCurrency(currency, new AsyncCallback<Void>() {

                public void onSuccess(Void result) {
                    getEventBus().fireEvent(new CurrencyChangedEvent(CurrencyEditPanel.this, currency));
                }

                public void onFailure(Throwable caught) {
                    Window.alert(caught.getMessage());
                }
            });
        }
    }
}
